#include "precompiled.h"
#include <ClanLib/display.h>
#include "MainWindow.h"
#include "EqualTemperament.h"

MainWindow::MainWindow(CL_GUIManager *manager, const CL_DisplayWindowDescription &desc)
	: CL_Window(manager, desc)
	, piano_engine(new EqualTemperament())
{

	CL_Font_Freetype font_freetype(get_gc(), "Resources/visitor1.ttf", 16);
	CL_FontDescription clanlib_font_desc;
	clanlib_font_desc.set_typeface_name("visitor");
	clanlib_font_desc.set_height(16);
	clanlib_font_desc.set_weight(400);
	manager->register_font(font_freetype, clanlib_font_desc);
	manager->set_css_document("Resources/GUIThemeAero/theme.css");

	func_input_pressed().set(this, &MainWindow::on_input_down);
	func_input_released().set(this, &MainWindow::on_input_up);
	//func_render().set(this, &MainWindow::on_render);
	func_close().set(this, &MainWindow::on_close);

	CL_ImageView* bg = new CL_ImageView(this);
	bg->set_image(CL_Sprite(this->get_gc(), "Resources/background.png"));
	bg->set_geometry(CL_Rect(CL_Point(0, 0), bg->get_image().get_size()));

	cb_fadein = new CL_CheckBox(this);
	cb_fadein->set_text("Synth fade in");
	cb_fadein->set_geometry(CL_Rect(40, 110, CL_Size(160, 40)));
	cb_fadein->func_state_changed().set(this, &MainWindow::on_checkbox_checked, cb_fadein);

	cb_fadeout = new CL_CheckBox(this);
	cb_fadeout->set_text("Synth fade out");
	cb_fadeout->set_geometry(CL_Rect(40, 130, CL_Size(160, 40)));
	cb_fadeout->func_state_changed().set(this, &MainWindow::on_checkbox_checked, cb_fadeout);
	cb_fadeout->set_checked(true);
}

static bool get_note_for_key(CL_InputEvent const& key, int* note)
{
	// it's important to note that the ascii value of ']' for example coincides with they keycode of
	// the win-key. So the following remapping really should be done this way.
	int right_bracket = 221, left_bracket = 219, slash = 191, dot = 190,
		comma = 188, equals = 187, semicolon = 186;

	std::map<int, int> notes;
	notes['Z'] = 0; notes['S'] = 1; notes['X'] = 2; notes['D'] = 3; notes['C'] = 4; notes['V'] = 5;
	notes['G'] = 6; notes['B'] = 7; notes['H'] = 8; notes['N'] = 9; notes['J'] = 10; notes['M'] = 11;
	notes[comma] = 12; notes['L'] = 13; notes[dot] = 14; notes[semicolon] = 15; notes[slash] = 16;
	notes['Q'] = 12; notes['2'] = 13; notes['W'] = 14; notes['3'] = 15; notes['E'] = 16; notes['R'] = 17;
	notes['5'] = 18; notes['T'] = 19; notes['6'] = 20; notes['Y'] = 21; notes['7'] = 22; notes['U'] = 23;
	notes['I'] = 24; notes['9'] = 25; notes['O'] = 26; notes['0'] = 27; notes['P'] = 28; notes[left_bracket] = 29;
	notes[equals] = 30; notes[right_bracket] = 31;
	if(notes.find(key.id) == notes.end()) return false;
	*note = notes[key.id];
	return true;
}

bool MainWindow::on_input_up(const CL_InputEvent &key)
{
	if(key.id == CL_KEY_ESCAPE)
	{
		on_close();
	}

	int note_id;
	if(get_note_for_key(key, &note_id))
	{
		piano_engine.begin_note_release(note_id);
	}
	return true;
}

bool MainWindow::on_input_down(const CL_InputEvent &key)
{
	if(key.repeat_count > 0) return false;
	int note_id;
	if(get_note_for_key(key, &note_id))
	{
		piano_engine.begin_playing_note(note_id);
	}
	return true;
}

void MainWindow::on_render( CL_GraphicContext &gc, const CL_Rect &clip_rect )
{
}

bool MainWindow::on_close()
{
	exit_with_code(0);
	return true;
}

void MainWindow::on_checkbox_checked( CL_CheckBox* checkbox )
{
	if(checkbox == cb_fadein)
	{
		if(cb_fadein->is_checked())
		{
			piano_engine.get_envelope_parameters()->set_attack(400);
		}
		else
		{
			piano_engine.get_envelope_parameters()->set_attack(0);
		}
	} else if(checkbox == cb_fadeout)
	{
		if(cb_fadeout->is_checked())
		{
			piano_engine.get_envelope_parameters()->set_release(1000);
		}
		else
		{
			piano_engine.get_envelope_parameters()->set_release(0);
		}
	}
}